<template>
  <base-container>
    <!-- 搜索栏：用 key 让不同页签强制重渲 -->
    <avue-table-search
      :key="`search-${tabStatus}`"
      :option="searchOption"
      v-model="searchParams"
      @search-change="loadTableSearch"
      @search-reset="loadTableSearchReset"
    >
      <template #menu-after>
        <!-- 其他按钮 -->
      </template>
    </avue-table-search>

    <base-table-card>
      <template #header-left>
        <!-- tabs 只绑定本地 tabStatus，不直接绑 searchParams -->
        <el-tabs v-model="tabStatus">
          <el-tab-pane :label="normalTabLabel" name="0" />
          <el-tab-pane :label="disabledTabLabel" name="1" />
        </el-tabs>
      </template>

      <template #header-right>
        <el-button type="primary" v-auth="[PERMS.MESSAGE.MSG_CATEGORY.ADD]" @click="handleAddDialog"
          >新增公告类目</el-button
        >
      </template>

      <avue-crud
        ref="crudRef"
        :option="tableOption"
        :data="tableData"
        v-model="formData"
        :page="page"
        :table-loading="tableLoading"
        @refresh-change="loadGetTableData"
        @current-change="loadTablePageChange"
        @size-change="loadTablePageSizeChange"
        @row-save="newLoadAdd"
        @row-update="loadEdit"
      >
        <template #menu="{ row }">
          <el-button type="primary" v-auth="[PERMS.MESSAGE.MSG_CATEGORY.UPDATE]" text @click="handleEdit(row)"
            >编辑</el-button
          >

          <!-- 正常：停用；停用：启用+删除 -->
          <template v-if="tabStatus === '0'">
            <el-button
              type="primary"
              v-auth="[PERMS.MESSAGE.MSG_CATEGORY.ENABLE_TABLE]"
              text
              @click="handleDisable(row)"
              >停用</el-button
            >
          </template>
          <template v-else>
            <el-button type="primary" v-auth="[PERMS.MESSAGE.MSG_CATEGORY.ENABLE_TABLE]" text @click="handleEnable(row)"
              >启用</el-button
            >
            <el-button type="primary" v-auth="[PERMS.MESSAGE.MSG_CATEGORY.DELETE_TABLE]" text @click="loadDel(row)"
              >删除</el-button
            >
          </template>
        </template>
      </avue-crud>
    </base-table-card>
  </base-container>
</template>

<script setup>
  /* ============================== Imports ============================== */

  import Option from "@/crudOption/message/category";
  import { ElMessageBox } from "element-plus";
  const { searchOption, tableOption } = Option();
  // 监听权限变化，更新操作栏是否显示
  tableOption.value.menu = computed(() =>
    hasAuth([
      PERMS.MESSAGE.MSG_CATEGORY.UPDATE,
      PERMS.MESSAGE.MSG_CATEGORY.ENABLE,
      PERMS.MESSAGE.MSG_CATEGORY.DELETE_TABLE,
    ])
  );
  /* ============================== 本地页签状态 ============================== */
  const tabStatus = ref("0"); // '0' 正常 | '1' 已停用

  /* ============================== 统计计数 & 标签 ============================== */
  const tabStats = reactive({ 1: 0, 0: 0 });
  const normalTabLabel = computed(() => `正常(${tabStats["0"]})`);
  const disabledTabLabel = computed(() => `已停用(${tabStats["1"]})`);

  /* ============================== CRUD Hook ============================== */
  let {
    data: tableData,
    loading: tableLoading,
    page,
    search: searchParams,
    form: formData,
    get: loadGetTableData,
    add: loadAdd,
    edit: loadEdit,
    del: loadDel,
    pageNumChange: loadTablePageChange,
    pageSizeChange: loadTablePageSizeChange,
    searchReset: loadTableSearchReset,
    searchChange: loadTableSearch,
  } = useCrudHook({
    get: Api.message.GetmsgCategoryList,
    add: Api.message.AddmsgCategory,
    edit: Api.message.EditmsgCategory,
    del: Api.message.DelMsgCategory,
    // 初始与 tabStatus 对齐
    search: { status: "0" },

    // 查询参数格式化
    getParamsFormat: params => {
      const p = { ...params };
      const split = (arr, [s, e]) => {
        if (Array.isArray(arr) && arr.length === 2) {
          p[s] = arr[0];
          p[e] = arr[1];
        }
      };

      // 统一的 timeRange，根据页签映射到不同字段
      if (String(p.status) === "1") {
        split(p.timeRange, ["stopDateBegin", "stopDateEnd"]);
      } else {
        split(p.timeRange, ["addDateBegin", "addDateEnd"]);
      }
      delete p.timeRange;

      split(p.updateTime, ["updateBeginDate", "updateEndDate"]);
      delete p.updateTime;

      return p;
    },

    // 提交前把 target 数组转成逗号分隔字符串
    addParamsFormat: row => ({
      categoryName: row.categoryName,
      target: Array.isArray(row.target) ? row.target.join(",") : row.target || "",
      indexSort: Number(row.indexSort ?? 1),
    }),
    editParamsFormat: row => ({
      id: row.id,
      categoryName: row.categoryName,
      target: Array.isArray(row.target) ? row.target.join(",") : row.target || "",
      indexSort: Number(row.indexSort ?? 1),
    }),
  });
  /* ================== 适用对象字典：全量 & 裁剪 ================== */
  // 1) 获取「适用对象」字段配置
  const getApplicableCol = () => tableOption.value?.group?.[0]?.column?.target;
  // 2) 全量字典缓存
  const ALL_APPLICABLE = ref([]);
  // 3) 拉取字典，并写入配置（根级默认显示全部）
  async function loadApplicableDict() {
    try {
      const res = await Api.dict.GetListChildrenByDictCode({
        dictCode: "qingyun.support.message.target",
      });
      ALL_APPLICABLE.value = (res?.data || []).map(i => ({
        label: i.dictLabel,
        value: String(i.dictValue),
      }));
    } finally {
      const col = getApplicableCol();
      if (col) col.dicData = ALL_APPLICABLE.value.slice();
    }
  }
  /* ============================== 统计接口 ============================== */

  async function loadGetTableStatistics() {
    try {
      const res = await Api.message.StatisticsMsgCategory({});
      const list = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [];
      const acc = { 1: 0, 0: 0 };
      for (const it of list) {
        const s = String(it.status);
        const c = Number(it.messageCount ?? 0);
        if (s === "1" || s === "0") acc[s] += c;
      }
      tabStats["1"] = acc["1"];
      tabStats["0"] = acc["0"];
    } catch {
      tabStats["1"] = 0;
      tabStats["0"] = 0;
    }
  }

  /* ============================== 选项（搜索/表格） ============================== */

  // 统一的时间选择配置
  const makeTimeRangeCfg = label => ({
    label,
    component: "el-date-picker",
    type: "daterange",
    format: "YYYY-MM-DD",
    valueFormat: "YYYY-MM-DD",
  });

  // 把“新增时间/停用时间”放在同一个占位：timeRange
  function applyStatusConfig() {
    // 1) 同位置的 timeRange：只换 label
    const newFormConfig = {
      ...searchOption.value.formConfig,
      timeRange: makeTimeRangeCfg(tabStatus.value === "1" ? "停用时间" : "新增时间"),
    };
    // 清掉历史遗留字段，避免渲染残留
    delete newFormConfig.createTime;
    delete newFormConfig.stopDate;

    // 替换整棵对象引用，确保 base-search 感知变化
    searchOption.value = {
      ...searchOption.value,
      formConfig: newFormConfig,
    };

    // 2) 表格列：固定使用 createTime 作为“列位锚点”，不删不加列，仅切换 label + 取值来源
    const anchor = tableOption.value.column.createTime || {};
    tableOption.value.column.createTime = {
      ...anchor,
      label: tabStatus.value === "1" ? "停用时间" : "新增时间",
      // 兼容两种实现：若表格支持 prop，这里切换 prop；
      // 若你的包装层忽略 prop，则依赖 formatter 取值，不影响列位置。
      prop: tabStatus.value === "1" ? "stopDate" : "createTime",
      formatter: row => (tabStatus.value === "1" ? row?.stopDate : row?.createTime),
      minWidth: anchor.minWidth ?? 170,
      type: anchor.type ?? "datetime",
      valueFormat: anchor.valueFormat ?? "YYYY-MM-DD HH:mm:ss",
      addDisplay: false,
      editDisplay: false,
    };
  }
  // 刷新列表同时执行数据变更
  function newLoadAdd(...args) {
    loadAdd(...args).then(() => loadGetTableStatistics());
  }
  /* ============================== Tabs 切换：唯一触发点 ============================== */
  watch(
    tabStatus,
    async v => {
      // 同步到查询条件
      searchParams.value.status = v;

      // 根据页签重配 搜索项/表格列（列位置保持不变）
      applyStatusConfig();

      // 拉数据 + 统计（一次各一条，不会重复）
      await Promise.all([loadApplicableDict(), loadGetTableData(), loadGetTableStatistics()]);
    },
    { immediate: true }
  ); // 首次进入也配置 & 拉一次

  /* ============================== 头部按钮/行操作 ============================== */
  const crudRef = ref(null);
  function handleAddDialog() {
    crudRef.value.rowAdd();
  }

  // 编辑
  function handleEdit(row) {
    crudRef.value?.rowEdit({
      id: row.id,
      categoryName: row.categoryName ?? "",
      indexSort: Number(row.indexSort ?? 1),
      // 一定给“target”（数组）
      target: Array.isArray(row.target)
        ? row.target
        : typeof row.target === "string"
          ? row.target
              .split(",")
              .map(s => s.trim())
              .filter(Boolean)
          : [],
    });

    nextTick(() => {
      crudRef.value?.$refs?.form?.clearValidate?.(["target"]);
    });
  }

  /** 统一改状态：to = 0(启用) | 1(停用) */
  async function handleChangeStatus(row, to) {
    const txt =
      to === 0
        ? "确定要启用该类目吗？启用后该类目下的所有公告将显示。"
        : "确定要停用该类目吗？停用后该类目下的所有公告将不显示。";
    await ElMessageBox.confirm(txt, "提示", { type: "warning" });

    await Api.message.StatusMsgCategoryChange({ id: row.id, status: to });

    $msg.success(to === 0 ? "已启用" : "已停用");
    await Promise.all([loadApplicableDict(), loadGetTableData(), loadGetTableStatistics()]);
  }
  const handleDisable = row => handleChangeStatus(row, 1).catch(() => {});
  const handleEnable = row => handleChangeStatus(row, 0).catch(() => {});
</script>

<style lang="scss" scoped></style>
